package com.gper.edu.innerclass

import com.gper.edu.innerclass

/**
 * scala的内部类的实例
 *
 *
 */
object InnerClassDemo {
  def main(args: Array[String]): Unit = {
    //创建一个外部类的对象
    val outer = new ScalaOuterClass
    val outer2 = new ScalaOuterClass
    /**
     * scala创建内部类的对象语法：new 外部类对象.内部类
     */
    val inner1 = new outer.ScalaInnerClass
    val inner11 = new outer2.ScalaInnerClass
    val inner2 = new outer2.ScalaInnerClass2
    //调用info方法
    inner1.info
    println("===============================================")
    inner11.info
    println("===============================================")
    inner2.info
    println("====================类型投影===========================")
    inner1.test(inner1)
//    inner1.test(inner11)  //这里会报错，因为inner1和inner11不是同一个外部对象创建的
    inner1.test2(inner11)  // 这里使用了类型投影，所以它是OK的
    //创建静态内部类
    val staticInner = new ScalaOuterClass.ScalaStaticInnerClass
    staticInner.info
  }
}


class ScalaOuterClass{
  /**
   * 通过别类来访问外部类的成员
   * 1. 使用别名的方式来访问外部类属性
   * outerObject可以理解为外部类的实例
   */
  outerObject =>
  class ScalaInnerClass2{
    def info = {
      println("name = "+outerObject.name+" sal : "+outerObject.sal)
    }
    def test(obj:ScalaInnerClass): Unit ={
      println(obj.toString)
    }
  }
  var name = "scoot"
  private var sal = 15560.0

  class ScalaInnerClass{
    /**
     * 内部类访问外部类的属性
     * 2. 外部类类名.this.属性
     */
    def info = {
      println("name = "+ScalaOuterClass.this.name+" sal : "+ScalaOuterClass.this.sal)
      println("name = "+name+" sal : "+sal)
    }

    def test(obj:ScalaInnerClass): Unit ={
      println(obj.toString)
    }

    /**
     * 这里有一个方法，可以接受ScalaInnerClass实例
     * 下面的ScalaOuterClass#ScalaInnerClass 类型投影的作用屏蔽外部对象对内部类对象的影响
     * @param obj
     */
    def test2(obj:ScalaOuterClass#ScalaInnerClass): Unit ={
      println(obj.toString)
    }
  }
}

object ScalaOuterClass{
  class ScalaStaticInnerClass{
    def info(): Unit ={
      println("static inner class.")
    }
  }
}